package objects;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.swing.Timer;

import start.Config;

/**
 * Steuerung und Animation des Pendels.
 *
 * @version 1.0
 * @author Dennis Wittkoetter
 * @author Imanuel Rohlfing
 */
public class Pendulum implements ActionListener {
    /**
     * TransformGroup des Pendels aus VRML
     */
    private TransformGroup pendulum;
    /**
     * Position des Pendelausschlags nach links oder rechts
     */
    private int position;
    /**
     * Richtung des Pendelausschlags (Wert positiv = rechts, Wert negativ =
     * links)
     */
    private int direction;
    /**
     * Pendelausschlagswinkel
     */
    private int degree;
    /**
     * Timer fuer Pendelausschlagsanimation (Pendelgeschwindigkeit)
     */
    private Timer timer;

    /**
     * Konstruiert das Pendel.
     *
     * @param pendulum	TransformGroup des Pendel-Objekts
     * 
     * @see Config#defaultPendulumSpeed
     */
    public Pendulum(TransformGroup pendulum) {
        this.pendulum = pendulum;
        pendulum.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        this.degree = 360;	//Start-Ausschlagswinkel
        this.position = 0;	//Startposition (Pendel haengt nach unten)
        this.direction = 1;	//Pendel schwingt zuerst nach rechts

        timer = new Timer(Config.defaultPendulumSpeed, this);
    }

    /**
     * Pendelanimation. Wird durch Timer ausgeloest.
     */
    public void actionPerformed(ActionEvent e) {
        /*
         * Maximalen Pendelausschlag festlegen
         * max. 20 Positionen nach links und rechts
         */
        if (position == 20) {
            direction = -1;
        }
        if (position == -20) {
            direction = 1;
        }

        //Aktuellen Pendelausschlag berechnen
        position += direction;

        /*
         * Schwingung simulieren (Pendel wird zum Ende des Ausschlags hin langsamer)
         * Keine physikalisch korrekte Berechnung! Nur gefaked, der Optik wegen...
         */
        if ((position > 10 && direction > 0)
        ||  (position < -10 && direction < 0)) {
            degree += 15;
        }
        if ((position >= 10 && direction < 0)
        ||  (position <= -10 && direction > 0)) {
            degree -= 15;
        }

        /*
         * Animation durchfuehren
         * Pendel wird abhaengig vom Winkel nud Position um die x-Achse rotiert.
         */
        Transform3D rotate = new Transform3D();
        rotate.rotX((Math.PI / degree) * position);
        pendulum.setTransform(rotate);
    }

    /**
     * Startet die Pendelanimtion.
     */
    public void start() {
        if (!timer.isRunning()) {
            timer.start();
        }
    }

    /**
     * Stoppt die Pendelanimation.
     */
    public void stop() {
        if (timer.isRunning()) {
            timer.stop();
        }
    }
}
